<?php

namespace App\Task;

use App\Common\RedisUtils;
use App\Common\Res;
use App\Common\SendMsgUtils;
use App\Common\SendTalkMsgUtils;
use App\Common\StringUtils;
use App\Constants\ConstCode;
use App\Constants\ErrorCode;
use App\Model\form\MessageTalkTrait;
use App\Model\form\UserDeviceTrait;
use App\Model\form\WeworkAccountTrait;
use App\Model\form\WeworkFriendTrait;
use App\Model\Task;
use App\Model\TaskAccount;
use App\Model\UserDevice;
use App\Model\WeworkAccount;
use App\Service\client\callBackService;
use App\Service\client\taskMobileService;
use Hyperf\DbConnection\Db;
use App\Job\QueueService;
use Hyperf\Di\Annotation\Inject;

class FooTask
{
    use Res, RedisUtils, SendMsgUtils, SendTalkMsgUtils,
        MessageTalkTrait, StringUtils, WeworkFriendTrait, UserDeviceTrait, WeworkAccountTrait;

    /**
     * @Inject
     * @var QueueService
     */
    protected $service;
    /**
     * 未发送心跳设备过期时间
     * @var float|int
     */
    protected $differTime = 1 * 60;


    /**
     * 检测有没待执行任务生成任务手机号
     *  crontab定时任务 检测设备任务并下发
     *  每一秒执行一次
     */
    public function appTaskCheck(): array
    {
        // try {
        var_dump('定时监测任务包中-----');

        $taskWhere = function ($query) {
            $query->where('status', ConstCode::IS_USE);
            $query->where('is_working', ConstCode::NO_WORKING);
            $query->where('start_time', '<=', date('H:i:s', time()));
            $query->where('end_time', '>', date('H:i:s', time()));
        };
        $taskList = Task::where($taskWhere)->get()->toArray();
        if (!empty($taskList)) {
            foreach ($taskList as $value) {
                $res = make(taskMobileService::class)->getTaskMobile($value);
                /*如果生成任务号码，则按照机制发放号码*/
                if ($res['code'] == ErrorCode::SUCCESS) {
                    return $this->Success('任务包处理成功');
                } else {
                    return $this->Error(ErrorCode::ERROR, '任务包处理失败');
                }
            }
        } else {
            //任务列表
            return $this->Error(ErrorCode::ERROR, '暂无任务处理');
        }
//        } catch (\Exception $e) {
//            return $this->Error(ErrorCode::ERROR, '任务包处理失败');
//        }
    }


    /**
     * 定时下发任务
     *  crontab定时任务 设备任务下发检测
     *  每一秒执行一次
     */
    public function sendAppTask(): array
    {
        //    try {
        var_dump('设备任务下发检测中-----');
        $taskWhere = function ($query) {
            $query->where('status', ConstCode::IS_USE);
            $query->where('is_working', ConstCode::IS_WORKING);
            $query->where('start_time', '<=', date('H:i:s', time()));
            $query->where('end_time', '>', date('H:i:s', time()));
        };
        $taskList = Task::where($taskWhere)->get()->toArray();
        if (!empty($taskList)) {
            foreach ($taskList as $task) {
                /*获取该任务下的账号列表*/
                $taskAccountList = TaskAccount::where(['task_id' => $task['id'], 'status' => ConstCode::IS_USE])->get()->toArray();
                if (!empty($taskAccountList)) {
                    foreach ($taskAccountList as $task_account) {
                        $token = trim($this->getUserDeviceToken(['marketUserId' => $task_account['marketUserId']]));
                        $device = $this->hGet($this->hKey, $token);
                        if (!empty($device)) {
                            $deviceArr = json_decode($device, true);
                            /*该设备不在任务中；就下发任务*/
                            if ($deviceArr['runing_status'] != 'runing_status') {
                                /*在任务范围内，生成该任务的批次号码*/
                                $task_account['device_id'] = $deviceArr['id'];
                                $result = make(taskMobileService::class)->sendTaskMobile($task, $task_account);
                                if (!empty($result)) {
                                    $data['mobile'] = $result['mobile'];
                                    $data['numberStr'] = $result['numberStr'];
                                    $data['bookname'] = $result['bookname'];
                                    $data['content'] = $task['content'];
                                    $data['status'] = 1;
                                    $data['msg'] = '设备任务下发成功';
                                    $result = $this->sendAppAddFriend($deviceArr['fd'], $data);
                                    var_dump('设备任务发送成功');
                                    // return $this->Success('设备任务发送成功');
                                } else {
                                    var_dump('没有待发送号码或者未到发送时间');
                                    // return $this->Error(ErrorCode::ERROR, '没有待发送号码或者未到发送时间');
                                }
                            } else {
                                var_dump('设备在任务中');
                                // return $this->Error(ErrorCode::ERROR, '设备在任务中');
                            }
                        }
                    }
                } else {
                    var_dump('任务账号为空');
                    //  return $this->Error(ErrorCode::ERROR, '任务账号为空');
                }
            }
            return $this->Success('设备任务全部发送成功');
        } else {
            return $this->Error(ErrorCode::ERROR, '暂无任务发送');
        }
//        } catch (\Exception $e) {
//            return false;
//        }
    }

    /**
     * 定时下发添加好友任务
     *  crontab定时任务 设备任务下发检测
     *  每一秒执行一次
     */
    public function sendAppFriendTask(): array
    {
        //    try {
        var_dump('设备号码任务下发检测中-----');
        $taskWhere = function ($query) {
            $query->where('status', ConstCode::IS_USE);
            $query->where('start_time', '<=', date('H:i:s', time()));
            $query->where('end_time', '>', date('H:i:s', time()));
        };
        $taskList = Task::where($taskWhere)->get()->toArray();
        if (!empty($taskList)) {
            foreach ($taskList as $task) {
                /*获取该任务下的账号列表*/
                $taskAccountList = TaskAccount::where(['task_id' => $task['id'], 'status' => ConstCode::IS_USE, 'restrict_status' => 0])->get()->toArray();
                if (!empty($taskAccountList)) {
                    foreach ($taskAccountList as $task_account) {
                        $marketUserId = $this->getWeworkAccountMarketUserId(['id' => $task_account['account_id']]);
                        $token = trim($this->getUserDeviceToken(['marketUserId' => $marketUserId]));
                        $device = $this->hGet($this->hKey, $token);
                        if (!empty($device)) {
                            $deviceArr = json_decode($device, true);
                            /*该设备不在任务中；就下发任务*/
                            if ($deviceArr['runing_status'] != 'runing_status') {
                                /*在任务范围内，生成该任务的批次号码*/
                                $task_account['device_id'] = $deviceArr['id'];
                                $result = make(taskMobileService::class)->sendTaskFriendMobile($task, $task_account);
                                if (!empty($result)) {
                                    var_dump('----------------准备下发设备任务fd------------' . $deviceArr['fd']);
                                    $data['mobile'] = $result['mobile'];
                                    $data['numberStr'] = $result['numberStr'];
                                    $data['bookname'] = $result['bookname'];
                                    $data['content'] = $task['content'];
                                    $data['status'] = 1;
                                    $data['msg'] = '设备任务下发成功';
                                    $data['fd'] = $deviceArr['fd'];
                                    $data['delay'] = $result['delay'];
                                    $this->service->push($data);
                                    //$result = $this->sendAppAddFriend($deviceArr['fd'], $data);
                                    // return $this->Success('设备任务发送成功');
                                } else {
                                    var_dump('_没有待发送号码或者未到发送时间');
                                    var_dump($task_account);
                                    // return $this->Error(ErrorCode::ERROR, '没有待发送号码或者未到发送时间');
                                }
                            } else {
                                var_dump('设备在任务中');
                                // return $this->Error(ErrorCode::ERROR, '设备在任务中');
                            }
                        }
                    }
                } else {
                    var_dump('任务账号为空');
                    //  return $this->Error(ErrorCode::ERROR, '任务账号为空');
                }
            }
            return $this->Success('设备任务全部发送成功');
        } else {
            return $this->Error(ErrorCode::ERROR, '暂无任务发送');
        }
//        } catch (\Exception $e) {
//            return false;
//        }
    }

    /**
     * 更新账号库里面哪些旧数据登录状态
     *  crontab定时任务 定时同步账号登录状态
     *  每60秒执行一次
     */
    public function checkAccountLoginTask(): bool
    {
        var_dump('定时任务检测账号登录状态中-----');
        Db::beginTransaction();
        try {
            $deviceList = UserDevice::whereNotNull('token')->get()->toArray();
            if (!empty($deviceList)) {
                foreach ($deviceList as $key => $value) {
                    /*查询是否登录*/
                    $token = $this->hGet($this->hKey, $value['token']);
                    if (empty($token)) {
                        $account = WeworkAccount::where(['marketUserId' => $value['marketUserId'], 'is_login' => 1])->first();
                        if (!empty($account)) {
                            $account->is_login = 0;
                            $account->save();
                        }
                    }
                }
            }
            Db::commit();
            //任务列表
            return true;
        } catch (\Exception $e) {
            Db::rollBack();
            return false;
        }
    }


    /**
     * 去除久未回应的心跳
     *  crontab定时任务 定时清除5分钟未心跳的设备信息
     *  每一秒执行一次
     */
    public function checkDevicePopTask(): bool
    {
        var_dump('定时任务检测设备心跳中-----');
        try {
            $list = $this->hGetAll($this->hKey);
            if (!empty($list)) {
                foreach ($list as $key => $value) {
                    $device = json_decode($value, true);
                    $time = time() - $device['popTime'];
                    if ($time >= $this->differTime) {
                        $account = WeworkAccount::where(['marketUserId' => $device['marketUserId'], 'is_login' => 1])->first();
                        if (!empty($account)) {
                            $account->is_login = 0;
                            $account->save();
                        }
                        $res = $this->hDel($this->hKey, $key);
                    }
                }
            }
            //任务列表
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }


    /**
     * 平台发送消息推给用户，整体推送
     *  crontab定时任务 半分钟检测推送一次
     *  每一秒执行一次
     */
    public function messageToFriend(): bool
    {
        var_dump('定时任务检测给好友推送消息中-----');
//        try {
        $allDevice = $this->hGetAll('device');
        $messageKeyList = $this->zRange('messageKey');
        $userArr = [];
        if (!empty($allDevice) && !empty($messageKeyList)) {
            /*算出有哪些用户*/
            foreach ($messageKeyList as $key) {
                $message = $this->hGet('message', $key);
                $messageArr = json_decode($message, true);
                if ($messageArr['direction'] == 0) {
                    $userArr[] = $messageArr['userId'];
                }
            }
            /*每一台设备区分不同人消息*/
            $userIdArr = array_values(array_unique($userArr));
            /*算出有哪些用户*/
            foreach ($allDevice as $key => $value) {
                $sendData = [];
                $deviceArr = json_decode($value, true);

                foreach ($userIdArr as $k => $v) {
                    foreach ($messageKeyList as $messageKey) {
                        $message = $this->hGet('message', $messageKey);
                        $messageArr = json_decode($message, true);
                        if ($messageArr['direction'] == 0) {
                            if ($deviceArr['id'] == $messageArr['device_id'] && $messageArr['is_send'] == 0) {
                                //$content = $this->getContentByType($messageArr['type'], $messageArr['content']);
                                $data = [
                                    'content' => $messageArr['content'],
                                    'isRoomMsg' => $messageArr['isRoomMsg'] == 1 ? true : false,
                                    'bookname' => $messageArr['bookname'],
                                    'nickname' => $messageArr['nickname'],
                                    'mobile' => $messageArr['mobile'],
                                    'sendId' => $messageArr['marketUserId'],
                                    'msgType' => $messageArr['type'],
                                    'key' => $messageKey,
                                    'timeStamp' => intval($messageArr['add_time']),
                                ];
                                if (!isset($sendData[$k])) {
                                    $sendData[$k] = ['list' => [], 'count' => 0];
                                }
                                if ($v == $messageArr['userId']) {
                                    $sendData[$k]['list'][] = $data;
                                    $sendData[$k]['count'] += 1;
                                } else {
                                    unset($sendData[$k]);
                                }
                            }
                        }
                    }
                }
                if (!empty($sendData)) {
                    $this->sendAppMessageToFriend($deviceArr['fd'], array_values($sendData));
                }

            }
        } else {
            var_dump('消息发送处设备为空或消息为空---------------');
        }
        //任务列表
        return true;
//        } catch (\Exception $e) {
//            return false;
//        }
    }

    /**
     * 用户发送消息推给平台
     *  crontab定时任务 定时清除5分钟未心跳的设备信息
     *  每一秒执行一次
     */
    public function messageToService(): bool
    {
        var_dump('定时任务检测给运营推送消息中-----');
        //    try {
        $allUserKey = $this->getChatAllKey();
        $messageKeyList = $this->zRange('messageKey');
        if (!empty($allUserKey) && !empty($messageKeyList)) {
            foreach ($allUserKey as $key) {
                $chat = $this->getChat($key);
                $chatArr = json_decode($chat, true);
                if (!empty($chatArr)) {
                    foreach ($messageKeyList as $messageKey) {
                        $message = $this->hGet('message', $messageKey);
                        $messageArr = json_decode($message, true);
                        if ($messageArr['direction'] == 1) {
                            if ($chatArr['id'] == $messageArr['operation_user_id'] && $messageArr['is_send'] == 0) {
                                $content = $this->getContentByType($messageArr['type'], $messageArr['content']);
                                // $content = $messageArr['content'];
                                $data['timeStamp'] = intval($messageArr['add_time']);
                                $data['receiverId'] = $messageArr['marketUserId'];
                                $data['sendId'] = $messageArr['userId'];
                                $data['error'] = 0;
                                $data['msgType'] = $messageArr['type'];
                                $data['content'] = $content;
                                $data['commandType'] = ConstCode::COMMAND_TYPE_ONE;
                                $this->sendMessageTalk($chatArr['fd'], $data);
                                make(callBackService::class)->appMessageToService($messageArr);
                            }
                        }
                    }
                }
            }
        } else {
            var_dump('消息发送处设备为空或消息为空---------------');
        }
        //任务列表
        return true;
//        } catch (\Exception $e) {
//            return false;
//        }
    }


}
